package com.sdyc.utils.files;

import com.sdyc.utils.beans.ClassUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.Properties;
import java.util.Set;

/**
 * 属性文件
 * Created by Rayn on 2015/11/29.
 */
public class PropeConfiguration
{
    /**
     * 序列化
     */
    private static final long serialVersionUID = 1L;


    /**
     * 配置信息
     */
    protected Properties properties;


    /**
     * 源配置路径
     */
    private final String resourcePath;


    /**
     * slf4j 日志方式
     */
    private final static Logger LOG = LoggerFactory.getLogger( PropeConfiguration.class );

    public PropeConfiguration ( String path ) {
        this.properties = PropertyUtil.loadProperties( path );
        this.resourcePath = PropertyUtil.getPropertiesFilePath( path );
    }

    public PropeConfiguration ( File file ) {
        this.properties = PropertyUtil.loadProperties( file );
        this.resourcePath = file.getAbsolutePath();
    }

    public PropeConfiguration ( Properties properties, String filePath ) {
        this.properties = properties;
        this.resourcePath = filePath;
    }

    public PropeConfiguration () {
        this.properties = new Properties();
        this.resourcePath = null;
    }

    public String getResourcePath() {
        return this.resourcePath;
    }

    public boolean containsProperty(String key) {
        return this.properties.containsKey(key);
    }

    public String getProperty(String key) {
        String value = this.properties.getProperty(key);
        if (value == null) {
            throw new IllegalStateException("no property with key '" + key + "' found");
        }
        return value;
    }

    public String getProperty(String key, String defaultValue) {
        String value = this.properties.getProperty(key);
        if (value == null) {
            value = defaultValue;
        }
        return value;
    }

    public void setProperty(String key, String value) {
        this.properties.setProperty(key, value);
    }

    protected void setProperty(String key, long value) {
        this.properties.setProperty(key, Long.toString(value));
    }

    public boolean getBoolean(String key, boolean defaultValue) {
        return Boolean.parseBoolean(getProperty(key, Boolean.toString(defaultValue)));
    }

    public int getInt(String key) {
        return Integer.parseInt(getProperty(key));
    }

    public int getInt(String key, int defaultValue) {
        try {
            return Integer.parseInt(getProperty(key));
        } catch (NumberFormatException e) {
            LOG.warn("failed to parse value '" + getProperty(key) + "' for key '" + key + "' - returning default value '"
                    + defaultValue + "'");
            return defaultValue;
        } catch (IllegalStateException e) {
            return defaultValue;
        }
    }

    public float getFloat(String key, float defaultValue) {
        try {
            return Float.parseFloat(getProperty(key));
        } catch (NumberFormatException e) {
            LOG.warn("failed to parse value '" + getProperty(key) + "' for key '" + key + "' - returning default value '"
                    + defaultValue + "'");
            return defaultValue;
        } catch (IllegalStateException e) {
            return defaultValue;
        }
    }



    public double getDouble(String key, double defaultValue) {
        try {
            return Double.parseDouble(getProperty(key));
        } catch (NumberFormatException e) {
            LOG.warn("failed to parse value '" + getProperty(key) + "' for key '" + key + "' - returning default value '" + defaultValue + "'");
            return defaultValue;
        } catch (IllegalStateException e) {
            return defaultValue;
        }
    }

    public File getFile(String key) {
        return new File(getProperty(key));
    }

    public Class<?> getClass(String key) {
        String className = getProperty(key);
        return ClassUtil.forName( className, Object.class );
    }

    public Class<?> getClass(String key, Class<?> defaultValue) {
        String className = getProperty(key, defaultValue.getName());
        return ClassUtil.forName(className, Object.class);
    }

    public Set<String> getKeys() {
        return this.properties.stringPropertyNames();
    }

    public Properties getPropertiesCopy() {
        return new Properties(this.properties);
    }
}
